package boerse.main.CommandProcessor;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import boerse.CommandProcessor.*;
import boerse.main.Account.AccountManager;
import boerse.main.Exceptions.*;

public class StockGameCommandProcessor {
	
	private AccountManager accountManager;
	private BufferedReader shellReader = new BufferedReader(new InputStreamReader(System.in));
	private PrintWriter shellWriter = new PrintWriter(System.out);
	
	public StockGameCommandProcessor(AccountManager accountManager) {
		super();
		this.accountManager = accountManager;
	}

	public void process() {
		CommandScanner scanner = new CommandScanner(StockGameCommandType.values(), shellReader);
		
		while (true) {
			
			try {				
				CommandDescriptor cmdDescriptor = new CommandDescriptor();
				
				scanner.fillInCommandDesc(cmdDescriptor);
					
				StockGameCommandType commandType = (StockGameCommandType) cmdDescriptor.getCommandType();
				
				if (commandType.equals(StockGameCommandType.HELP)) {
					StockGameCommandType[] commands = StockGameCommandType.values();
					String helpText = "";
					
					for (int i = 0; i < commands.length; i++) {
						helpText += commands[i].getCmdName() + ": " + commands[i].getHelpText() + "\n";
					}
					shellWriter.print(helpText);
					
				} else if (commandType.equals(StockGameCommandType.EXIT)) {
					return;
				
				} else {
					Object[] param = cmdDescriptor.getParams();
					
					Method m = AccountManager.class.getDeclaredMethod(commandType.getMethodName(), commandType.getParamTypes());
					Object returnValue = m.invoke(accountManager, param);
					
					if (returnValue != null)
						shellWriter.print(returnValue);
				}
							
				shellWriter.print("succsess");
					
			} catch (FalseCommandException e) {
				shellWriter.print("false command\n");
				
			} catch (FalseParametersException e) {
				shellWriter.print("false parameters\n");
												
			} catch (NoSuchMethodException e) {
				shellWriter.print("error in command list");
				
			} catch (SecurityException e) {
				shellWriter.print("error in command list");
				
			} catch (IllegalAccessException e) {
				shellWriter.print("error in command list");
				
			} catch (IllegalArgumentException e) {
				shellWriter.print("error in command list");
				
			} catch (InvocationTargetException e) {
				Class<?> er = e.getCause().getClass();
				
				if (er == NotEnoughMoneyException.class)
					shellWriter.print("not enough money\n");
				else if (er == NegativeShareCountException.class)
					shellWriter.print("no more share to sell\n");
				else if(er == NegativeValueException.class)
					shellWriter.print("negative value\n");
				else if(er == NoSuchPlayerException.class)
					shellWriter.print("no such player in system\n");
				else if(er == NoSuchShareException.class)
					shellWriter.print("no such share in system\n");
				else
					shellWriter.print("unknow error");
					
			} finally {
				shellWriter.print("\n\n");
				shellWriter.flush();
			}
		}
	}
	
}
